import "./index.css";
import "../css/animate.min.css";
import {
    addQipao,
    setPrizes,
    setPrizeData
} from "./prizeList";
import {
    NUMBER_MATRIX,
    configWidth,
    configHeight,
    atmosphereGroupCard
} from "./config.js";

// 设定参数
const ROTATE_TIME = 1000;
let TOTAL_CARDS,
    Order,
    nowScenes,
    btns = {
        enter: document.querySelector("#enter"),
        lottery: document.querySelector("#lottery"),
        operate: document.querySelector("#operate"),
        next: document.querySelector("#next")
    },
    prizes,
    EACH_COUNT,
    ROW_COUNT = 9,
    COLUMN_COUNT = 21,
    HIGHLIGHT_CELL = [],
    // 当前的比例
    Resolution = 1;

let camera,
    scene,
    renderer,
    controls,
    threeDCards = [],
    targets = {
        table: [],
        sphere: []
    };

let selectedCardIndex = [],
    rotate = false,
    basicData = {
        prizes: [], //奖品信息
        users: [], //所有人员
        luckyUsers: {}, //已中奖人员
        leftUsers: [] //未中奖人员
    },
    // 正在抽奖
    isLotting = false,
    currentLuckys = [];
/**
 * 点击进入抽奖界面
 */
function handleEnter() {
    document.querySelector("#toggle-main-page").addEventListener("click", function (e) {
        $('.main-page').show();
        $('.code-main').hide();
        //去请求
        initAll();
    });

    document.querySelector("#menu").addEventListener("click", function (e) {
        e.stopPropagation();
        // 如果正在抽奖，则禁止一切操作'
        let target = e.target.id;

        if (!['reset', 'back'].includes(target)) {
            if (isLotting) {
                addQipao("抽慢一点点～～抽奖还没结束");
                return false;
            }
            let perCount = EACH_COUNT,
                leftCount = basicData.leftUsers.length
            const notAllowed = perCount > leftCount

            if (notAllowed) {
                addQipao("池中已经没有人拉,请重置抽奖人员池");
                return false;
            }
        }

        switch (target) {
            // 进入抽奖
            case "enter":
                // 更换音乐
                replaceMusic(basicData.prizes.enter)
                // 清除高亮卡片
                removeHighlight();
                // 弹出提示
                // addQipao(`马上抽取[${basicData.prizes.title}],不要走开。`);
                // 弹出提示
                addQipao(`正在抽取[${basicData.prizes.title}],调整好姿势`);
                rotate = true;
                // 切换场景
                switchScreen("lottery");
                break;
            // 颁奖模式
            case "awards":
                replaceMusic(basicData.prizes.awards)
                break;
            // 抽奖
            case "lottery":
                // 更新剩余抽奖数目的数据显示
                setPrizeData(basicData.prizes)
                //更新状态
                setLotteryStatus(true);
                // 抽奖
                lottery();
                break;
            case "next":
                btns.operate.classList.add("hidden");
                document.getElementById("container").innerHTML = '';
                initAll();
                break;
        }
    });
    window.addEventListener("resize", onWindowResize, false);
}
handleEnter();
/**
 * 初始化所有DOM
 */
function initAll() {
    fetch("https://choujiang.itcat365.cn/api/api/system/show_user/get_start_user_info/").then(res => res.json()).then(res => {
        basicData.users = res.start_user.concat(res.other_user);
        basicData.luckyUsers = res.start_user;
        basicData.leftUsers = res.other_user;
        Order = res.order;
        // 设置奖项
        prizes = {
            count: res.product.number,
            text: res.product.text,
            title: res.product.title,
            enter: "other-lottery",
            awards: "other-BJ-BGM",
            ROTATE_TIME: 10000,
            circle: res.product.order * 8
        }
        switch (res.order) {
            case 1:
                prizes.img = "./img/edifier.jpg"
                prizes.enter = "other-lottery"
                prizes.awards = "other-BJ-BGM"
            case 2:
                prizes.img = "./img/ipad.jpg"
                prizes.enter = "other-lottery"
                prizes.awards = "other-BJ-BGM"
            case 3:
                prizes.img = "./img/mbp.jpg"
                prizes.enter = "other-lottery"
                prizes.awards = "other-BJ-BGM"
            case 4:
                prizes.img = "./img/huawei.png"
                prizes.enter = "1st-lottery"
                prizes.awards = "1st-BJ-BGM"
        }
        // 一次抽多少个数
        EACH_COUNT = prizes.count;
        // 创建高亮
        HIGHLIGHT_CELL = createHighlight();
        // 设置奖项
        basicData.prizes = prizes; //基础奖项配置
        setPrizes(prizes);

        // 总卡片数
        TOTAL_CARDS = ROW_COUNT * COLUMN_COUNT;

        // 格式化用户信息
        const newUser = [];
        for (var i = 0; i < basicData.users.length; i++) {
            let arr = [];
            arr.push(basicData.users[i].openid)
            arr.push(basicData.users[i].nickname)
            arr.push(basicData.users[i].headimgurl)
            newUser[i] = arr
        }

        basicData.users = newUser.sort(randomsort);

        initCards();
        animate();
    })
}

function randomsort(a, b) {
    return Math.random() > .5 ? -1 : 1;
    //用Math.random()函数生成0~1之间的随机数与0.5比较，返回-1或1
}

// 初始化卡片
function initCards() {
    threeDCards = [];
    targets = {
        table: [],
        sphere: []
    };
    selectedCardIndex = [];
    let member = basicData.users,
        length = member.length;

    let isBold = false,
        showTable = true,
        index = 0,
        position = {
            x: (140 * COLUMN_COUNT - 20) / 2,
            y: (180 * ROW_COUNT - 20) / 2
        };

    camera = new THREE.PerspectiveCamera(
        45,
        configWidth / configHeight,
        1,
        10000
    );
    camera.position.z = 3000;

    scene = new THREE.Scene();

    for (let i = 0; i < ROW_COUNT; i++) {
        for (let j = 0; j < COLUMN_COUNT; j++) {
            isBold = HIGHLIGHT_CELL.includes(j + "-" + i);
            var element = createCard(
                member[index % length],
                isBold,
                index,
                showTable
            );
            var object = new THREE.CSS3DObject(element);
            object.position.x = Math.random() * 4000 - 2000;
            object.position.y = Math.random() * 4000 - 2000;
            object.position.z = Math.random() * 4000 - 2000;
            scene.add(object);
            threeDCards.push(object);

            var object = new THREE.Object3D();
            object.position.x = j * 140 - position.x;
            object.position.y = -(i * 180) + position.y;
            targets.table.push(object);
            index++;
        }
    }

    // sphere

    var vector = new THREE.Vector3();
    for (var i = 0, l = threeDCards.length; i < l; i++) {
        var phi = Math.acos(-1 + (2 * i) / l);
        var theta = Math.sqrt(l * Math.PI) * phi;
        var object = new THREE.Object3D();
        threeDCards[i].userData = {
            id: basicData.users[i][0]
        }
        targets.table[i].userData = {
            id: basicData.users[i][0]
        }
        object.userData = {
            id: basicData.users[i][0]
        }
        object.position.setFromSphericalCoords(800 * Resolution, phi, theta);
        vector.copy(object.position).multiplyScalar(2);
        object.lookAt(vector);
        targets.sphere.push(object);
    }

    renderer = new THREE.CSS3DRenderer();
    renderer.setSize(configWidth, configHeight);
    document.getElementById("container").appendChild(renderer.domElement);

    controls = new THREE.TrackballControls(camera, renderer.domElement);
    controls.rotateSpeed = 0.5;
    controls.minDistance = 500;
    controls.maxDistance = 6000;
    controls.addEventListener("change", render);
    switchScreen("enter");
}

// 设置抽奖状态
function setLotteryStatus(status = false) {
    isLotting = status;
}

//场景转换
function switchScreen(type) {
    switch (type) {
        case "enter":
            transform(targets.table, 2000, () => {
                btns.enter.classList.remove("hidden");
                btns.lottery.classList.add("hidden");
                shineCard();
            });
            break;
        case "next":
            btns.enter.classList.remove("hidden");
            btns.operate.classList.add("hidden");
            transform(targets.table, 2000,);
            break;
        default:
            btns.enter.classList.add("hidden");
            transform(targets.sphere, 2000, () => {
                // btns.lottery.classList.remove("hidden");
                btns.lottery.click();
            });
            break;
    }
}

/**
 * 创建元素
 */
function createElement(css, text) {
    let dom = document.createElement("div");
    dom.className = css || "";
    dom.innerHTML = text || "";
    return dom;
}

/**
 * 创建名牌
 */
function createCard(user, isBold, id, showTable) {
    var element = createElement();
    element.id = "card-" + id;

    if (isBold) {
        element.className = "element lightitem";

        if (showTable) {
            element.classList.add("highlight");
        }
        //feat@刷新后不显示默认背景色
        element.style.backgroundColor = atmosphereGroupCard()
    } else {
        element.className = "element";
        element.style.backgroundColor = atmosphereGroupCard()
    }
    //添加公司标识
    element.appendChild(createElement("company", `<img src="${user[2]} " />`));

    element.appendChild(createElement("name", user[1]));

    return element;
}

// 移除高亮
function removeHighlight() {
    document.querySelectorAll(".highlight").forEach(node => {
        node.classList.remove("highlight");
    });
}

/**
 * 渲染地球等
 */
function transform(targets, duration, callback) {
    for (var i = 0; i < threeDCards.length; i++) {
        var object = threeDCards[i];
        var target = targets[i];
        threeDCards[i].userData = target.userData;
        new TWEEN.Tween(object.position)
            .to(
                {
                    x: target.position.x,
                    y: target.position.y,
                    z: target.position.z
                },
                Math.random() * duration + duration
            )
            .easing(TWEEN.Easing.Exponential.InOut)
            .start();

        new TWEEN.Tween(object.rotation)
            .to(
                {
                    x: target.rotation.x,
                    y: target.rotation.y,
                    z: target.rotation.z
                },
                Math.random() * duration + duration
            )
            .easing(TWEEN.Easing.Exponential.InOut)
            .start();
    }

    new TWEEN.Tween(this)
        .to({}, duration * 2)
        .onUpdate(render)
        .start().onComplete(() => {
            callback && callback();
        });
}

//旋转地球
function rotateBall() {
    return new Promise((resolve, reject) => {
        scene.rotation.y = 0;
        new TWEEN.Tween(scene.rotation)
            .to(
                {
                    y: Math.PI * (basicData.prizes && basicData.prizes.circle || 8)
                },
                basicData.prizes && basicData.prizes.ROTATE_TIME || ROTATE_TIME
            )
            .onUpdate(render)
            .easing(TWEEN.Easing.Exponential.InOut)
            .start()
            .onComplete(() => {
                resolve();
            });
    });
}

// 浏览器窗口变化
function onWindowResize() {
    camera.aspect = configWidth / configHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(configWidth, configHeight);
    render();
}

// 动画
function animate() {
    requestAnimationFrame(animate);
    TWEEN.update();
    controls.update();
}

// 渲染
function render() {
    renderer.render(scene, camera);
}

// 选中中奖人员
function selectCard(duration = 600) {
    rotate = false;
    let width = 140,
        tag = -(currentLuckys.length - 1) / 2,
        locates = [];

    // 计算位置信息, 大于5个分两排显示
    if (currentLuckys.length > 20) {
        let yPosition = [-200, 50, 300],
            l = selectedCardIndex.length,
            mid = Math.ceil(l / 3);
        tag = -(mid - 1) / 3;
        for (let i = 0; i < mid; i++) {
            locates.push({
                x: tag * width * Resolution - 180,
                y: yPosition[0] * Resolution
            });
            tag++;
        }

        tag = -(mid - 1) / 3;
        for (let i = mid; i < mid * 2; i++) {
            locates.push({
                x: tag * width * Resolution - 180,
                y: yPosition[1] * Resolution
            });
            tag++;
        }

        tag = -(l - mid * 2 - 1) / 3;
        for (let i = mid * 2; i < l; i++) {
            locates.push({
                x: tag * width * Resolution - 180,
                y: yPosition[2] * Resolution
            });
            tag++;
        }
    }
    else if (currentLuckys.length > 10) {
        let yPosition = [-87, 87],
            l = selectedCardIndex.length,
            mid = Math.ceil(l / 2);
        tag = -(mid - 1) / 2;
        for (let i = 0; i < mid; i++) {
            locates.push({
                x: tag * width * Resolution,
                y: yPosition[0] * Resolution
            });
            tag++;
        }

        tag = -(l - mid - 1) / 2;
        for (let i = mid; i < l; i++) {
            locates.push({
                x: tag * width * Resolution,
                y: yPosition[1] * Resolution
            });
            tag++;
        }
    } else {
        for (let i = selectedCardIndex.length; i > 0; i--) {
            locates.push({
                x: tag * width * Resolution,
                y: 0 * Resolution
            });
            tag++;
        }
    }

    let text = currentLuckys.map(item => item[1]);
    addQipao(
        `恭喜${text.join("、")}获得${basicData.prizes.title}, 新的一年必定旺旺旺。`
    );

    selectedCardIndex.forEach((cardIndex, index) => {
        changeCard(cardIndex, currentLuckys[index]);
        var object = threeDCards[cardIndex];
        new TWEEN.Tween(object.position)
            .to(
                {
                    x: locates[index].x,
                    y: locates[index].y * Resolution,
                    z: 1200
                },
                Math.random() * duration + duration
            )
            .easing(TWEEN.Easing.Exponential.InOut)
            .start();

        new TWEEN.Tween(object.rotation)
            .to(
                {
                    x: 0,
                    y: 0,
                    z: 0
                },
                Math.random() * duration + duration
            )
            .easing(TWEEN.Easing.Exponential.InOut)
            .start();

        object.element.classList.add("prize");
        tag++;
    });

    new TWEEN.Tween(this)
        .to({}, duration * 2)
        .onUpdate(render)
        .start()
        .onComplete(() => {
            // 动画结束后可以操作
            setLotteryStatus();
            btns.next.disabled = Order == 4;
            btns.next.textContent = Order != 4 ? '开始下一轮' : '没有奖品了'
            btns.operate.classList.remove("hidden");
        });
}

/**
 * 重置抽奖牌内容
 */
function resetCard(duration = 500) {

    if (currentLuckys.length === 0) {
        return Promise.resolve();
    }
    selectedCardIndex.forEach(index => {
        let object = threeDCards[index],
            target = targets.sphere[index];
        threeDCards[index].userData = targets.sphere[index].userData;
        new TWEEN.Tween(object.position)
            .to(
                {
                    x: target.position.x,
                    y: target.position.y,
                    z: target.position.z
                },
                Math.random() * duration + duration
            )
            .easing(TWEEN.Easing.Exponential.InOut)
            .start();
        new TWEEN.Tween(object.rotation)
            .to(
                {
                    x: target.rotation.x,
                    y: target.rotation.y,
                    z: target.rotation.z
                },
                Math.random() * duration + duration
            )
            .easing(TWEEN.Easing.Exponential.InOut)
            .start();
    });

    return new Promise((resolve, reject) => {
        new TWEEN.Tween(this)
            .to({}, duration * 2)
            .onUpdate(render)
            .start()
            .onComplete(() => {
                selectedCardIndex.forEach(index => {
                    let object = threeDCards[index];
                    object.element.classList.remove("prize");
                });
                resolve();
            });
    });
}

/**
 * 抽奖
 */
function lottery() {
    btns.lottery.classList.add("hidden");
    rotateBall().then(() => {
        const newUser = [];
        for (var i = 0; i < basicData.luckyUsers.length; i++) {
            let arr = [];
            arr.push(basicData.luckyUsers[i].openid)
            arr.push(basicData.luckyUsers[i].nickname)
            arr.push(basicData.luckyUsers[i].headimgurl)
            newUser[i] = arr
        }
        currentLuckys = newUser
        currentLuckys.map(item => {
            let index = threeDCards.findIndex(ch => ch.userData.id == item[0]);
            selectedCardIndex.push(index)
        })

        selectCard();
    });
}

/**
 * 随机抽奖
 */
function random(num) {
    // Math.floor取到0-num-1之间数字的概率是相等的
    return Math.floor(Math.random() * num);
}

function changeCard(cardIndex, user) {
    let card = threeDCards[cardIndex].element;
    // 要替换的数据
    let oldData = threeDCards[cardIndex].userData;
    let sjIndex = threeDCards.findIndex(item => item.userData.id == user['0']);
    threeDCards[sjIndex].userData = oldData;
    threeDCards[cardIndex].userData = {
        id: user['0']
    }
    const nameDom = `<div class="name">${user['1']
        }</div>`
    const companyDom = `<div class="company"><img src="${user['2']} " /></div>`
    card.innerHTML = nameDom + companyDom
}

/**
 * 切换名牌背景
 */
function shine(cardIndex, color) {
    let card = threeDCards[cardIndex].element;
    card.style.backgroundColor =
        color || atmosphereGroupCard();
}

/**
 * 随机切换背景和人员信息
 */
function shineCard() {
    let maxCard = 10,
        maxUser;
    let shineCard = 10 + random(maxCard);

    setInterval(() => {
        // 正在抽奖停止闪烁
        if (isLotting) {
            return;
        }
        maxUser = basicData.users.length;
        for (let i = 0; i < shineCard; i++) {
            let index = random(maxUser),
                cardIndex = random(TOTAL_CARDS);
            // 当前显示的已抽中名单不进行随机切换
            if (selectedCardIndex.includes(cardIndex)) {
                continue;
            }
            shine(cardIndex);
            changeCard(cardIndex, basicData.users[index]);
        }
    }, 500);
}

// 创建高亮
function createHighlight() {
    let year = new Date().getFullYear() + "";
    let step = 5,
        xoffset = 1,
        yoffset = 1,
        highlight = [];

    year.split("").forEach(n => {
        highlight = highlight.concat(
            NUMBER_MATRIX[n].map(item => {
                return `${item[0] + xoffset}-${item[1] + yoffset}`;
            })
        );
        xoffset += step;
    });
    return highlight;
}

/**
 * @description: 替换音乐
 * @param {*} scenes 场景值对应音乐名
 * @return {*}
 * @Date: 2022-01-19 14:46:05
 */
function replaceMusic(scenes) {
    if (nowScenes == scenes) return
    let music = document.querySelector("#music");
    music.src = `./data/${scenes}.m4a`
    musicBox.click()
    nowScenes = scenes

}

// 初始化
let onload = window.onload;
window.onload = function () {
    onload && onload();

    let music = document.querySelector("#music");
    let rotated = 0,
        stopAnimate = false,
        musicBox = document.querySelector("#musicBox");

    function animate() {
        requestAnimationFrame(function () {
            if (stopAnimate) {
                return;
            }
            rotated = rotated % 360;
            musicBox.style.transform = "rotate(" + rotated + "deg)";
            rotated += 1;
            animate();
        });
    }

    musicBox.addEventListener(
        "click",
        function (e) {
            if (music.paused) {
                music.play().then(
                    () => {
                        stopAnimate = false;
                        animate();
                    },
                    () => {
                        addQipao("背景音乐自动播放失败，请手动播放！");
                    }
                );
            } else {
                music.pause();
                stopAnimate = true;
            }
        },
        false
    );

    setTimeout(function () {
        replaceMusic("enter-BGM")
    }, 2000);
};
